<?php

namespace App\Models;

use App\Libraries\Tree;
use App\Models;

class NavbarModel extends ComModel
{

    public $tablename;
    private $navbars;

    public function __construct()
    {
        parent::__construct();
        $this->tablename = 'navbar';
    }

    //新增和编辑全部数据时验证
    private function _validate($data, $id = 0)
    {
        if (!$data) {
            return ams_rt(1, '请填写相关数据');
        }

        $data = esc($data);

        if (isset($data['url']) && $data['url']) {
            $data['url'] = esc($data['url']);
        }

        if (!$data['name']) {
            return ams_rt(1, '名称必须填写');
        } elseif (!$data['tid']) {
            return ams_rt(1, '分类必须选择');
        }
        return ams_rt(0, 'ok', $data);
    }

    public function get($id)
    {
        $data = $this->db->table($this->tablename)->where('id', $id)->limit(1)->get()->getRowArray();
        if ($data && $data['thumb']) {
            $data['thumb_info'] = $this->db->table('attachment')->select('filename,attachment')->where('id', intval($data['thumb']))->get()->getRowArray();
        }
        return ams_rt(0, 'ok', $data);
    }

    public function getNavbarsByTid($tid)
    {
        $tid = intval($tid);
        $data = [];
        $_data = $this->db->table($this->tablename)->where('tid', $tid)->orderBy('displayorder ASC,id ASC')->get()->getResultArray();
        if (!$_data) {
            return $data;
        }
        foreach ($_data as $t) {
            $data[$t['id']] = $t;
        }
        if ($data) {
            $tree = new Tree();
            $data = $tree->get($data);
        }
        return $data;
    }

    public function add($data)
    {
        $rt = $this->_validate($data);
        if ($rt['code'] != 0) {
            return $rt;
        }
        $data = $rt['data'];

        $insert = array(
            'tid' => $data['tid'],
            'pid' => isset($data['pid']) ? (int) $data['pid'] : 0,
            'pids' => '',
            'name' => $data['name'],
            'url' => $data['url'],
            'title' => (isset($data['title']) && $data['title']) ? $data['title'] : $data['name'],
            'enname' => (isset($data['enname']) && $data['enname']) ? $data['enname'] : '',
            'show' => (isset($data['show']) && $data['show']) ? 1 : 0,
            'enname' => (isset($data['enname']) && $data['enname']) ? $data['enname'] : $data['name'],
            'thumb' => (isset($data['thumb']) && $data['thumb']) ? intval($data['thumb']) : 0,
            'childids' => '',
            'displayorder' => 0,
        );

        $this->db->table($this->tablename)->insert($insert);
        $id = $this->db->insertID();
        if ($id) {
            if (isset($data['thumb']) && $data['thumb']) {
                $related = $this->tablename . '-' . $id;
                $this->db->table('attachment')->where('id', intval($id))->update(['related' => $related]);
            }
            $this->repair($data['tid']);
            return ams_rt(0, '操作成功', $id);
        }
        return ams_rt(1, '操作失败');
    }

    public function edit($id, $data)
    {
        $rt = $this->_validate($data, $id);
        if ($rt['code']) {
            return $rt;
        }
        $data = $rt['data'];
        $updata = [
            'tid' => $data['tid'],
            'pid' => isset($data['pid']) ? (int) $data['pid'] : 0,
            'name' => $data['name'],
            'url' => $data['url'],
            'title' => (isset($data['title']) && $data['title']) ? $data['title'] : $data['name'],
            'enname' => (isset($data['enname']) && $data['enname']) ? $data['enname'] : '',
            'show' => (isset($data['show']) && $data['show']) ? 1 : 0,
            'enname' => (isset($data['enname']) && $data['enname']) ? $data['enname'] : $data['name'],
            'thumb' => (isset($data['thumb']) && $data['thumb']) ? intval($data['thumb']) : 0,
        ];
        $this->db->table($this->tablename)->where('id', $id)->update($updata);
        if (isset($updata['thumb']) && $updata['thumb']) {
            $related = $this->tablename . '-' . $id;
            $this->db->table('attachment')->where('id', intval($id))->update(['related' => $related]);
        }
        $this->repair($data['tid']);
        return ams_rt(0, '操作成功', $updata);
    }

    public function clear($tid = 0)
    {
        $rows = $this->db->table($this->tablename)->where('tid', $tid)->get()->getResultArray();
        if (!$rows) {
            return ams_rt(0, '操作成功');
        }
        foreach ($rows as $k => $row) {
            $data = $this->db->select('id')->where('tid', $tid)->get($this->tablename)->result_array();
            if ($data) {
                foreach ($data as $v) {
                    $id = $this->navbar_model->delete_for_id($v['id']);
                    $id && $this->attachment_model->delete_for_table($this->tablename . '-' . $id);
                }
            }
        }
    }

    public function del($id = 0)
    {
        if (!$id) {
            return ams_rt(1, '操作失败:参数错误');
        }
        $row = $this->db->table($this->tablename)->select('id,name,show,thumb')->where('id', intval($id))->get()->getRowArray();
        if ($row) {
            $this->db->table($this->tablename)->where('id', intval($id))->delete();
            if ($row['thumb']) {
                $this->db->table('attachment')->where('id', intval($row['thumb']))->delete();
            }
        }
        return ams_rt(0, 'ok', $row);
    }

    public function switchShow($id, $value)
    {
        if (!$id) {
            return ams_rt(1, '参数错误');
        }
        $row = $this->db->table($this->tablename)->select('id,name,show')->where('id', $id)->get()->getRowArray();
        if (!$row) {
            return ams_rt(1, '数据不存在');
        }
        $this->db->table($this->tablename)->where('id', $id)->update(['show' => $value]);
        return ams_rt(0, '操作成功', $row);
    }

    private function get_navbars($data = [])
    {
        if (is_array($data)) {
            foreach ($data as $catid => $c) {
                $this->navbars[$catid] = $c;
                $result = array();
                foreach ($this->navbars as $_k => $_v) {
                    $_v['pid'] && $result[] = $_v;
                }
            }
        }
        return true;
    }

    private function get_pids($catid, $pids = '', $n = 1)
    {
        if ($n > 50 || !is_array($this->navbars) || !isset($this->navbars[$catid])) {
            return false;
        }
        $pid = $this->navbars[$catid]['pid'];
        $pids = $pids ? $pid . ',' . $pids : $pid;
        if ($pid) {
            $pids = $this->get_pids($pid, $pids, ++$n);
        } else {
            $this->navbars[$catid]['pids'] = $pids;
        }
        return $pids;
    }

    private function get_childids($catid, $n = 1)
    {

        $childids = $catid;
        if ($n > 5 || !is_array($this->navbars) || !isset($this->navbars[$catid])) {
            return $childids;
        }

        if (is_array($this->navbars)) {
            foreach ($this->navbars as $id => $cat) {
                if ($cat['pid']
                    && $id != $catid
                    && $cat['pid'] == $catid) {
                    $childids .= ',' . $this->get_childids($id, ++$n);
                }
            }
        }

        return $childids;
    }

    private function get_data($tid)
    {
        $data = $this->db->table($this->tablename)->where('tid', $tid)->get()->getResultArray();
        if ($data) {
            foreach ($data as $k => $v) {
                $rows[$v['id']] = $v;
            }
        } else {
            $rows = [];
        }
        return $rows;
    }

    public function repair($tid)
    {
        $this->navbars = $navbars = [];
        $this->navbars = $navbars = $this->get_data($tid);
        $this->get_navbars($navbars);
        if (is_array($this->navbars)) {
            foreach ($this->navbars as $catid => $cat) {
                $pids = $this->get_pids($catid);
                $childids = $this->get_childids($catid);
                $child = is_numeric($childids) ? 0 : 1;

                $this->navbars[$catid]['pids'] = $pids;
                $this->navbars[$catid]['child'] = $child;
                $this->navbars[$catid]['childids'] = $childids;

                if ($navbars[$catid]['pids'] != $pids || $navbars[$catid]['childids'] != $childids || $navbars[$catid]['child'] != $child) {
                    $this->db->table($this->tablename)->where('id', $catid)->update(['pids' => $pids, 'child' => $child, 'childids' => $childids]);
                }
            }
        }
        //重新生成缓存
        $this->cacheData();
    }

    //上级
    public function get_select($tid)
    {
        $data = $_data = [];
        $data = $this->db->table($this->tablename)->where('tid', $tid)->orderBy('displayorder', 'asc')->orderBy('id', 'asc')->get()->getResultArray();
        if ($data) {
            $tree = new Tree();
            $data = $tree->get($data);
            foreach ($data as $k => $v) {
                $_data[$v['id']] = $v;
            }
        }
        return $_data;
    }

    /**
     *
     * 分类管理
     */
    public function limit_page_type($page = 1, $size = 10, $param = [])
    {
        $page = max(1, (int) $page);
        if ($param) {
            $param = esc($param);
        }
        $total = $this->db->table($this->tablename . '_cat')->countAllResults();
        $data = $this->db->table($this->tablename . '_cat')->limit($size, $size * ($page - 1))->get()->getResultArray();
        if (!$data) {
            $data = [];
        }
        return [$data, $total, $param];
    }

    public function getAllType()
    {
        $data = [];
        $_data = $this->db->table($this->tablename . '_cat')->get()->getResultArray();
        if ($_data) {
            foreach ($_data as $v) {
                $data[$v['id']] = $v;
            }
        }
        return $data;
    }

    public function getOneType($id)
    {
        $data = $this->db->table($this->tablename . '_cat')->where('id', $id)->get()->getRowArray();
        if (!$data) {
            $data = [];
        }
        return $data;
    }

    public function addType($data = [])
    {
        $data = esc($data);
        if (!$data['name']) {
            return ams_rt(1, '请填写分类名称');
        } elseif ($this->db->table($this->tablename . '_cat')->where('name', $data['name'])->countAllResults()) {
            return ams_rt(1, '名称已存在');
        }
        $id = $this->db->table($this->tablename . '_cat')->insert($data);
        if ($id) {
            return ams_rt(0, '操作成功', $data);
        }
        return ams_rt(1, '操作失败', $data);
    }

    public function editType($id, $data = [])
    {
        if (!$id) {
            return ams_rt(1, '参数错误');
        }
        $data = esc($data);
        if (!$data['name']) {
            return ams_rt(1, '请填写分类名称');
        } elseif ($this->db->table($this->tablename . '_cat')->where('name', $data['name'])->where('id<>' . $id)->countAllResults()) {
            return ams_rt(1, '名称已存在');
        }
        $rt = $this->db->table($this->tablename . '_cat')->where('id', $id)->update($data);
        if (!$rt) {
            return ams_rt(1, '操作失败', $data);
        }
        return ams_rt(0, '操作成功', $data);
    }

    public function delType($id = 0)
    {
        $id = intval($id);
        if (!$id) {
            return ams_rt(1, '参数错误');
        }
        $row = $this->db->table($this->tablename . '_cat')->where('id', $id)->get()->getRowArray();
        $this->db->table($this->tablename . '_cat')->where('id', $id)->delete();
        //删除链接
        $this->db->table($this->tablename)->where('tid', $id)->delete();
        return ams_rt(0, '操作成功', $row);
    }

    public function cacheData()
    {
        $type = $this->cache->get('navbarType');
        $cache = [];

        if ($type && is_array($type)) {
            foreach ($type as $tid => $name) {
                if ($tid && $name) {
                    $navbar = $this->db->table($this->tablename)->where('tid', $tid)->orderBy('displayorder ASC, id ASC')->get()->getResultArray();
                    if ($navbar) {
                        $CAT = $CAT_DIR = $level = array();
                        foreach ($navbar as $c) {
                            $pid = explode(',', $c['pids']);
                            $level[] = substr_count($c['pids'], ',');
                            $c['topid'] = isset($pid[1]) ? $pid[1] : $c['id'];
                            $c['catids'] = explode(',', $c['childids']);
                            $CAT[$c['id']] = $c;
                        }
                        $cache[$tid] = $CAT;
                    } else {
                        $cache[$tid] = [];
                    }
                }
            }
        }

        $this->cache->save('navbar', $cache, YEAR);
    }
}
